#!/usr/bin/env node
var http = require('http');
var path = require('path');
var fs = require('fs');
var utils = require('./js/utils');
var JSZip = require('jszip');
var finish_cnt = 0;


function zipRecurse(zip, dir, zipDir) {
    var dirList = fs.readdirSync(dir);
    dirList.forEach(function(item){
        var fullName = dir + '/' + item;
        if(fs.statSync(fullName).isDirectory()){
            zipRecurse(zip, fullName, zipDir+'/'+item);
        }else{
            zip.folder(zipDir).file(item, fs.readFileSync(fullName));
        }
    });
}
function zipFolder(zip, dir, zipDir) {
    zipRecurse(zip, dir, zipDir);
    return zip.generate({base64:false, compression:'DEFLATE'});
}

function postFileToServer(file, cnt, hostname, port) {
    var options = {
        hostname,
        port,
        path: '/postfile',
        method: 'POST'
    };

    var fullName = path.join(process.cwd(), file);
    console.log(fullName);
    if (fs.existsSync(fullName)) {
        var zip = new JSZip(),
            zipData;
        if (fs.statSync(fullName).isDirectory()) {
            zipData = zipFolder(zip, fullName, file);
        } else {
            zip.file(file, fs.readFileSync(fullName));
            zipData = zip.generate({base64: false, compression: 'DEFLATE' });
        }

        http.request(options, function(res) {
            res.on('data', function () {
                console.log('success');
                finish_cnt++;
                if (finish_cnt>=cnt) {
                    disconnectServer(hostname, port);
                }
            }).on('error', function(e) {
                console.log('error: ' + e.message);
                disconnectServer(hostname, port);
            });
        }).end(zipData, "binary");
    } else {
        console.log("error: no file");
        disconnectServer(hostname, port);
    }
}

function getFileFromServer(file, cnt, hostname, port) {
    var options = {
        hostname,
        port,
        path: "/getfile?file="+file,
        agent: false
    };
    var req = http.get(options, function(res) {
        res.pipe(require('unzipper').Extract({path: "."}));
        res.on('end', function(){
           console.log("get "+file+" success");
            finish_cnt++;
            if (finish_cnt>=cnt) {
                disconnectServer(hostname, port);
            }
        });
    }).on('error', function(e) {
        console.log("error: " + e.message);
        disconnectServer(hostname, port);
    });
}

function putTextToServer(text, hostname, port) {
	var options = {
        hostname,
        port,
        path: "/puttext?text="+text,
        agent: false
    };
    console.log(options);
    var req = http.get(options, function(res) {
        res.on('data', function(){
        }).on('end', function(){
			 console.log("success");
            disconnectServer(hostname, port);
        });
    }).on('error', function(e) {
        console.log("error: " + e.message);
        disconnectServer(hostname, port);
    });
}

function getTextFromServer(hostname, port) {
	var options = {
        hostname,
        port,
        path: "/gettext?text="+text,
        agent: false
    };
    var req = http.get(options, function(res) {
		var text = "";
        res.on('data', function(t) {
			text += t;
		}).on('end', function(){
			console.log(text);
			utils.copy(text);
            disconnectServer(hostname, port);
        });
    }).on('error', function(e) {
        console.log("error: " + e.message);
        disconnectServer(hostname, port);
    });
}

function disconnectServer(hostname, port) {
    var options = {
        hostname,
        port,
        path: "/disconnect",
        agent: false
    };
    var req = http.get(options, function(res) {
        res.on('end', function(){
           console.log("finish");
        });
    }).on('error', function(e) {
        console.log("error: " + e.message);
    });
}

function showHelp() {
    console.log("Usage: put/get files folders");
    console.log("     xf ip:port put xx.txt xx");
    console.log("     xf ip:port get xx.txt xx");
    console.log("     xf ip:port puttext text");
    console.log("     xf ip:port gettext");
}

var params = process.argv.slice(2);
if (!/^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))):[1-9]\d*$/.test(params[0])) {
    showHelp();
    process.exit(0);
}
var ip = params[0].split(':')[0];
var port = params[0].split(':')[1];

params = params.slice(1);
if (params[0] == 'put') {
    var files = params.slice(1);
    for (var i in files) {
        postFileToServer(files[i], files.length, ip, port);
    }
} else if (params[0] == 'get') {
    var files = params.slice(1);
    for (var i in files) {
        getFileFromServer(files[i], files.length, ip, port);
    }
} else if (params[0] == 'puttext') {
    var text = params.slice(1);
	if (!text || !text.length) {
		utils.paste(function(t) {
			putTextToServer(t, ip, port);
		});
	} else {
		putTextToServer(text, ip, port);
	}
} else if (params[0] == 'gettext') {
    getTextFromServer(ip, port);
} else {
    showHelp();
}
